/*
 *    Webical - http://www.webical.org
 *    Copyright (C) 2007 Func. Internet Integration
 *
 *    This file is part of Webical.
 *
 *    $Id: MonthDayRepeater.java 249 2012-07-29 19:49:31Z hz0885@gmail.com $
 *
 *    This program is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.webical.web.component.calendar;

import java.util.Arrays;
import java.util.Date;
import java.util.GregorianCalendar;

import org.apache.wicket.behavior.AttributeAppender;
import org.apache.wicket.markup.repeater.RepeatingView;
import org.apache.wicket.model.Model;
import org.webical.util.CalendarUtils;
import org.webical.web.action.IAction;
import org.webical.web.component.calendar.model.EventsModel;
import org.webical.web.component.calendar.model.WrappingEventsModel;

/**
 * Repeater for repeating days in the Month View
 *
 * @author Mattijs Hoitink
 *
 */
public abstract class MonthDayRepeater extends RepeatingView {
	private static final long serialVersionUID = 1L;

	/**
	 * CSS Class name for current day
	 */
	private static final String TODAY_CSS_CLASS = "todayItemMonth";
	/**
	 * CSS Class name for the first item in the repeater.
	 */
	private static final String FIRST_ITEM_CSS_CLASS = "firstItem";
	/**
	 * CSS Class name for the last item in the repeater.
	 */
	private static final String LAST_ITEM_CSS_CLASS = "lastItem";
	/**
	 * CSS Class name for items out of the months range
	 */
	private static final String OUT_OF_RANGE_CSS_CLASS = "outOfRange";
	
	/** Contains the actions this panel can handle */
	protected  static Class[] PANELACTIONS = new Class[] { };

	/**
	 * Constructor.
	 * @param id The ID to use in markup
	 * @param eventsModel The {@code EventsModel} to use.
	 * @param rangeMonth The month this range is representing
	 */
	public MonthDayRepeater(String id, EventsModel eventsModel, int rangeMonth) {
		super(id);

		GregorianCalendar todayCal = CalendarUtils.newTodayCalendar(eventsModel.getFirstDayOfWeek());
		Date todayStartDate = CalendarUtils.getStartOfDay(todayCal.getTime());

		GregorianCalendar startCal = CalendarUtils.newTodayCalendar(eventsModel.getFirstDayOfWeek());
		startCal.setTime(eventsModel.getStartDate());

		for (int i = 0; i <= 6; ++ i)
		{
			Date dayStartDate = startCal.getTime();
			Date dayEndDate = CalendarUtils.getEndOfDay(dayStartDate);

			// Add a MonthDayPanel for each day in the week
			MonthDayPanel monthDayPanel = new MonthDayPanel("day" + startCal.get(GregorianCalendar.DAY_OF_YEAR), new WrappingEventsModel(dayStartDate, dayEndDate, eventsModel)){
				private static final long serialVersionUID = 1L;

				@Override
				public void onAction(IAction action) {
					//MonthDayRepeater.this.handleAction(actionName, actionParameters);
					if (Arrays.asList(MonthDayRepeater.PANELACTIONS).contains(action.getClass())) {
						// Handle panel actions here
					} else {
						// Pass the action to the parent component
						MonthDayRepeater.this.onAction(action);
					}
				}
			};
			// Check if we need to add some extra css styles
			if (CalendarUtils.getStartOfDay(startCal.getTime()).compareTo(todayStartDate) == 0) {
				monthDayPanel.add(new AttributeAppender("class", true, new Model(TODAY_CSS_CLASS), " "));
			}
			if (i == 0) {
				monthDayPanel.add(new AttributeAppender("class", true, new Model(FIRST_ITEM_CSS_CLASS), " "));
			}
			if (i == 6) {
				monthDayPanel.add(new AttributeAppender("class", true, new Model(LAST_ITEM_CSS_CLASS), " "));
			}
			// Check if the date is in range
			if (!(startCal.get(GregorianCalendar.MONTH) == rangeMonth)) {
				monthDayPanel.add(new AttributeAppender("class", true, new Model(OUT_OF_RANGE_CSS_CLASS), " "));
			}
			add(monthDayPanel);

			// Add a day to the calendar
			startCal.add(GregorianCalendar.DAY_OF_YEAR, 1);
		}
	}

	/**
	 * Handle actions generated by this panel
	 * @param action The action to handle
	 */
	public abstract void onAction(IAction actionName);
}
